<template>
  <div>
    <input type="file" @change="onChange" />
  </div>
</template>

<script setup lang="ts">
import SparkMD5 from "spark-md5";

const onChange = (event: Event) => {
  // 文件
  const file = (event.target as HTMLInputElement).files?.[0]!;
  // 切片大小
  const chunkSize = 1024 * 1024 * 2;
  // 切片数量
  const chunks = Math.ceil(file.size / chunkSize);
  // 当前切片下标
  let currentChunk = 0;
  // SparkMD5 实例
  const spark = new SparkMD5.ArrayBuffer();
  // fileReader 实例
  const fileReader = new FileReader();

  // 读取成功
  fileReader.onload = function () {
    // 读取到的内容
    const result = this.result as ArrayBuffer;
    // 将该 result 追加到 计算hash 的操作中
    spark.append(result);
    // currentChunk++
    currentChunk++;
    // 判断是否全部读取完成
    if (currentChunk < chunks) {
      // 计算下一个
      loadNext();
    } else {
      // 全部读取完成了，完成hash的计算
      const hash = spark.end();
      console.log("全部读取完成，最终hash为", hash);
    }
  };

  // 读取失败
  fileReader.onerror = function (error) {
    console.log("读取失败", error);
  };

  // 定义一个 loadNext 方法
  function loadNext() {
    console.log(`read ${currentChunk + 1} of ${chunks}`);
    // 开始字节
    const start = currentChunk * chunkSize;
    // 结束字节
    const end = start + chunkSize >= file.size ? file.size : start + chunkSize;
    // 切片
    const chunk = file.slice(start, end);
    // 读取该切片的内容
    fileReader.readAsArrayBuffer(chunk);
  }

  // 默认调用一次 loadNext
  loadNext();
};
</script>
